#include "linux/err.h"
#include "linux/mfd/si476x-core.h"
#include <linux/spi/spi.h>
#include <linux/module.h>
#include <linux/poll.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/miscdevice.h>
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/mutex.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/stat.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/tty.h>
#include <linux/kmod.h>
#include <linux/gfp.h>
#include <linux/gpio/consumer.h>
#include <linux/platform_device.h>
#include <linux/of_gpio.h>
#include <linux/of_irq.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/slab.h>
#include <linux/fcntl.h>
#include <linux/timer.h>

static int major;
static struct spi_device *g_spi;
static struct class *spi_class;


static DECLARE_WAIT_QUEUE_HEAD(gpio_wait);
struct fasync_struct *spi_fasync;


/* 实现对应的open/read/write等函数，填入file_operations结构体                   */
static ssize_t spi_drv_read (struct file *file, char __user *buf, size_t size, loff_t *offset)
{
	// int err;

	// struct spi_transfer msgs[2];

	/* 初始化 spi_transfer */

	// static inline int
    //   spi_sync_transfer(struct spi_device *spi, struct spi_transfer *xfers,
	//   unsigned int num_xfers);

	/* copy_to_user  */
	
	return 0;
}

static ssize_t spi_drv_write(struct file *file, const char __user *buf, size_t size, loff_t *offset)
{
	//int err;

	/* copy_from_user  */


	// struct spi_transfer msgs[2];

	/* 初始化 spi_transfer */

	// static inline int
    //   spi_sync_transfer(struct spi_device *spi, struct spi_transfer *xfers,
	//   unsigned int num_xfers);

	
	return 0;    
}


static unsigned int spi_drv_poll(struct file *fp, poll_table * wait)
{
	//printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);
	poll_wait(fp, &gpio_wait, wait);
	//return is_key_buf_empty() ? 0 : POLLIN | POLLRDNORM;
	return 0;
}

static int spi_drv_fasync(int fd, struct file *file, int on)
{
	if (fasync_helper(fd, file, on, &spi_fasync) >= 0)
		return 0;
	else
		return -EIO;
}

static struct file_operations spi_drv = {
    .owner = THIS_MODULE,
    .read    = spi_drv_read,
	.write   = spi_drv_write,
	.poll    = spi_drv_poll,
	.fasync  = spi_drv_fasync,
};

static int my_spi_probe(struct spi_device *spi)
 {

    g_spi = spi;

    //注册字符设备驱动
    major = register_chrdev(0, "spi_drv", &spi_drv);

    spi_class = class_create(THIS_MODULE, "spi_class");
    if(IS_ERR(spi_class))
    {
        printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);
		unregister_chrdev(major, "spi_drv");
		return PTR_ERR(spi_class);
    }

    device_create(spi_class, NULL, MKDEV(major, 0), NULL, "my_spi"); /* /dev/my_spi */

    return 0;
 }


 //MCP2515设备移除函数
static int my_spi_remove(struct spi_device*spi)
{

    device_destroy(spi_class, MKDEV(major, 0));
	class_destroy(spi_class);
	unregister_chrdev(major, "spi_drv");

    return 0;
}


 //MCP2515设备匹配表,用于设备树匹配
static const struct of_device_id my_spi_of_match_table[] = {
    {.compatible = "my-spi"},
    {},
 };
 //MCP2515设备ID匹配表,用于总线匹配
static const struct spi_device_id my_spi_id_table[] = {
    {"my-spi",0},
    {},
 };

static struct spi_driver my_spi_drv = {
    .probe = my_spi_probe,//探测函数
    .remove = my_spi_remove,//移除函数
    .driver={
        .name = "hhk_spi_drv",//驱动名称
        .owner = THIS_MODULE,//所属模块
        .of_match_table = my_spi_of_match_table,//设备树匹配表
    },
    .id_table = my_spi_id_table,//设备ID匹配表
};


static int __init spi_drv_init(void)
{   
     int ret;
    //注册SPI驱动
    ret=spi_register_driver(&my_spi_drv);
    if(ret<0){
        //注册失败,打印错误信息
        printk("spi_register_drivererror\n");
        return ret;
    }
    return ret;

}

static void __exit spi_drv_exit(void)
{
    spi_unregister_driver(&my_spi_drv);
}



module_init(spi_drv_init);
module_exit(spi_drv_exit);
MODULE_LICENSE("GPL");












